﻿using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;

namespace XxlJobDotNetCore.Extension
{
    public static class WebApplicationBuilderExtension
    {
        private static IDisposable _callbackRegistration;
        /// <summary>
        /// 注册至Consul
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="isRegisterConsul"></param>
        /// <returns></returns>
        /// <exception cref="NullReferenceException"></exception>
        public static WebApplicationBuilder ConfigureDefault(this WebApplicationBuilder builder,  bool isRegisterConsul = false)
        {
            builder.Configuration.AddJsonFile(AppContext.BaseDirectory + "/appsettings." + builder.Environment.EnvironmentName + ".json", optional: true, reloadOnChange: true);
            if (isRegisterConsul)
            {
                ConsulConfig consulConfig = (builder.Configuration.GetSection("Consul") ?? throw new NullReferenceException("consulSection")).Get<ConsulConfig>();
                if (consulConfig == null)
                {
                    throw new NullReferenceException("consulOption");
                }
                builder.Configuration.AddConsulConfiguration(consulConfig, reloadOnChanges: true);
            }

            OnSettingConfigurationChanged(builder.Configuration);
            builder.Services.ReplaceConfiguration(builder.Configuration);

            builder.WebHost.ConfigureKestrel(delegate (WebHostBuilderContext context, KestrelServerOptions serverOptions)
            {
                IConfigurationSection section = context.Configuration.GetSection("Kestrel");
                if (section == null)
                    throw new NullReferenceException("kestrelSection");
                serverOptions.Configure(section);
            });
            return builder;
        }
        private static void OnSettingConfigurationChanged(object state)
        {
            _callbackRegistration?.Dispose();
            IConfiguration obj = state as IConfiguration;
            IEnumerable<IConfigurationSection> children = obj.GetChildren();
            IChangeToken reloadToken = obj.GetReloadToken();
            _callbackRegistration = reloadToken.RegisterChangeCallback(OnSettingConfigurationChanged, state);
        }
    }

    public class ConsulConfig
    {
        public string ConsulUrl { get; set; } = string.Empty;
        public string ConsulKeyPath { get; set; } = string.Empty;
    }
}
